package com.flyme.excel.load;

import com.ycc.base.common.Result;
import com.ycc.base.framework.web.login.LoginContext;
import com.ycc.base.framework.web.login.LoginSessionVo;
import com.zuche.framework.common.SpringApplicationContext;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by user on 2017/12/8.
 *
 * @author 上传并导入数据
 */
@Controller
@RequestMapping("/excelImport")
public class ExcelImportController {
    private static Logger logger = LoggerFactory.getLogger(ExcelImportController.class);
    @Autowired
    private LoginContext loginContext;

    /**
     * 进入导入页面
     *
     * @return
     */
    @RequestMapping("/toExcelImport")
    public ModelAndView toExcelImport(HttpServletRequest request) {
        ModelAndView view = new ModelAndView("/common/importFile");
        Map map = new HashMap<>();
        map.put("serviceName", request.getParameter("serviceName"));
        map.put("title", request.getParameter("title"));
        map.put("sheetName", request.getParameter("sheetName"));
        view.addObject("globalData", map);
        return view;
    }

    @ResponseBody
    @RequestMapping(value = "/importData", method = RequestMethod.POST)
    public Result importData(HttpServletRequest request, HttpServletResponse response) {
        Result res = Result.getServiceError();
        try {

            MultipartHttpServletRequest req = (MultipartHttpServletRequest) request;
            if (req.getFileMap() == null || req.getFileMap().values().size() == 0) {
                return Result.getServiceError("excel文件不能为空", "excel文件不能为空");
            }
            String serviceName = request.getParameter("serviceName");
            if (StringUtils.isEmpty(serviceName)) {
                return Result.getServiceError("serviceName不能为空", "serviceName不能为空");
            }
            ExcelImport excelImport = (ExcelImport) SpringApplicationContext.getBean(serviceName);
            if (excelImport == null) {
                return Result.getServiceError("服务不存在", "服务不存在");
            }
            //获得参数实际类型
            Class c = getParamClass(excelImport);
            if (c == null) {
                return Result.getServiceError("服务参数不正确", "服务参数不正确");
            }
            Collection<List<MultipartFile>> files = req.getMultiFileMap().values();
            Iterator<List<MultipartFile>> it = files.iterator();
            //---用户信息
            LoginSessionVo user = loginContext.getLoginSessionVo();
            if (user == null) {
                logger.info("获取当前用户为空，设置默认值:(0)");
                user = new LoginSessionVo();
                user.setId(0L);
            }
            while (it.hasNext()) {
                MultipartFile multipartFile = it.next().get(0);
                int excelType = multipartFile.getOriginalFilename().endsWith(".xls") ? 1 : 0;
                List list = ExcelImportUtil.getDataList(excelType, multipartFile, c);
                if (CollectionUtils.isEmpty(list)) {
                    return Result.getServiceError("excel文件内容不能为空", "excel文件内容不能为空");
                }

                res = excelImport.save(list ,user);
                //退出当前循环，只处理第一个文件
                break;
            }
        } catch (ExcelImportException e) {
            if (e.getMessage().contains("\n")) {
                res.setMsg(e.getMessage().substring(0, e.getMessage().lastIndexOf("\n")));
            } else {
                res.setMsg(e.getMessage());
            }
            logger.error("导入数据异常：", e);
        } catch (Exception e) {
            res.setMsg("导入数据异常");
            logger.error("导入数据异常：", e);
        }

        return res;

    }

    /**
     * 获取参数实际类型
     *
     * @param excelImport
     * @return
     */
    private Class getParamClass(ExcelImport excelImport) {
        Method[] methods = excelImport.getClass().getMethods();
        Class paramType = null;
        for (Method m : methods) {
            if (m.getName().equals("save")) {
                Type[] types = m.getGenericParameterTypes();
                Type type = types[0];
                if (type instanceof ParameterizedType) {
                    Type[] typesto = ((ParameterizedType) type).getActualTypeArguments();
                    paramType = (Class) typesto[0];
                }
                break;
            }
        }
        return paramType;
    }

    @ResponseBody
    @RequestMapping(value = "/downExcelImportTemplate")
    public void downExcelImportTemplate(HttpServletRequest request, HttpServletResponse response) {
        try {
            String serviceName = request.getParameter("serviceName");
            String sheetName = request.getParameter("sheetName") == null ? "Excel模板" : request.getParameter("sheetName");
            ExcelImport excelImport = (ExcelImport) SpringApplicationContext.getBean(serviceName);
            //获得参数实际类型
            Class c = getParamClass(excelImport);
            //获取Excel字段
            Field[] fs = c.getDeclaredFields();
            List<String> cellList = new ArrayList<>();
            for (int i = 0; i < fs.length; i++) {
                if (fs[i].getAnnotation(ExcelImportField.class) != null) {
                    cellList.add(fs[i].getAnnotation(ExcelImportField.class).cellName());
                }
            }
            response.setHeader("content-type", "text/html;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-disposition", "attachment;filename="
                    + URLEncoder.encode(sheetName, "UTF-8") + ".xls");
            InputStream inputStream = ExcelImportUtil.getExcelTemplate(cellList, sheetName);
            int len;
            byte[] bytes = new byte[1024];
            OutputStream outputStream = response.getOutputStream();
            while ((len = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, len);
            }

            outputStream.flush();
            response.flushBuffer();
        } catch (IOException e) {
            logger.error("下载导入模板异常：", e);
        }
    }
}
